package com.enzoism.springboot.dive.chapter01;

import java.util.concurrent.*;

/**
 * 要点一：CompleteFuture比Future多了获取结果的方法completableFuture.whenComplete((s, throwable))
 * 要点二：从CompletionFuture和Future对比可知：CompletionFuture更推荐结合lambda表达式使用
 * 要点三：public static <U> CompletableFuture<U> supplyAsync(Supplier<U> supplier,Executor executor)
 *
 * @link https://blog.csdn.net/DJH2717/article/details/89756110
 */
public class TestCompleteFuture {

    public static void main(String[] args) throws ExecutionException, InterruptedException {
        ExecutorService cachePool = Executors.newCachedThreadPool();
        // 1、测试Future
        // testFuture(cachePool);
        // 2、测试CompleteFuture
        testCompleteFuture(cachePool);

        cachePool.shutdown();
    }

    // 测试Future
    public static void testFuture(ExecutorService cachePool) throws ExecutionException, InterruptedException {
        Future<String> future = cachePool.submit(() -> {
            Thread.sleep(3000);
            return "异步任务计算结果!";
        });

        long start = System.currentTimeMillis();
        while (true) {
            if (future.isDone()) {
                System.out.println("----------->查询结果:" + future.get());
                break;
            }
        }
        System.out.println("轮询耗时:" + (System.currentTimeMillis() - start));
    }

    // 测试CompleteFuture
    public static void testCompleteFuture(ExecutorService cachePool) throws ExecutionException, InterruptedException {
        CompletableFuture<String> completableFuture = new CompletableFuture<>();

        // 第一步：completableFuture.complete
        cachePool.execute(() -> {
            try {
                Thread.sleep(3000);
                System.out.println("----------->completableFutureOne.complete()-before");
                completableFuture.complete("我就是爱音乐，别让我停下来！");
                System.out.println("----------->completableFutureOne.complete()-after");
                System.out.println(Thread.currentThread().getName());
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });

        // 第二步：completableFuture.whenComplete：WhenComplete 方法返回的 CompletableFuture 仍然是原来的 CompletableFuture 计算结果.
        CompletableFuture<String> completableFutureTwo = completableFuture.whenComplete((s, throwable) -> {
            System.out.println("----------->completableFutureOne.whenComplete()：" + s);
        });

        // 第三步：ThenApply 方法返回的是一个新的 completeFuture.
        CompletableFuture<Integer> completableFutureThree = completableFutureTwo.thenApply(s -> {
            System.out.println("----------->当异步任务执行结束时, 根据上一次的异步任务结果, 继续开始一个新的异步任务!");
            System.out.println("----------->completableFutureTwo.thenApply()：" + s);
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            return s.length();
        });
        System.out.println("----------->completableFutureThree.get()：" + completableFutureThree.get());
    }
}
